#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <iconv.h>
#include <errno.h>

#include "icar.h"
#include "icar_log.h"
#include "icar_utils.h"


static int code_convert(char *from_charset, char *to_charset, const char *inbuf, int inlen, char *outbuf, int outlen);

char
chtoi(char c)
{
	return ((c >= '0' && c <= '9') ? c - '0' : (c >= 'a' && c <= 'f') ? (c - 'a' + 10) : (c - 'A' + 10));
}

void * icar_malloc(size_t size) {
	void *retval = NULL;
	retval = malloc(size);

	if (!retval) {
		icar_daemon(LOG_CRIT, "Failed to malloc %d bytes of memory: %s. Bailing out", size, strerror(errno));
		exit(1);
	}

	return retval;
}

static int
code_convert(char *from_charset, char *to_charset, const char *inbuf, int inlen, char *outbuf, int outlen)
{
	iconv_t cd;
	char **pin = (char **)&inbuf;
	char **pout = &outbuf;
	int size;
	int out = outlen;

	cd = iconv_open(to_charset, from_charset);
	if (cd == NULL)
		return -1;

	memset(outbuf, 0, outlen);
	size = iconv(cd, pin, (size_t *__restrict__)(&inlen),
			pout, (size_t *__restrict__)(&outlen));

	iconv_close(cd);

	return (size == -1 ? size : out - outlen);
}

/*
   inbuf为需要转换格式的字符串，inlen为字符串长度；
   outbuf为转换后字符串，outlen为可转换的长度;
   返回值：成功，返回成功的字节数；失败，返回－1
 */
int
utf2Gbk(const char *inbuf, int inlen, char *outbuf, int outlen)
{
	return code_convert("utf-8", "gbk", inbuf, inlen, outbuf, outlen);
}

int
gbk2Utf(const char *inbuf, int inlen, char *outbuf, int outlen)
{
	return code_convert("gbk", "utf-8", inbuf, inlen, outbuf, outlen);
}
